/*
 * Copyright © 2018 www.noark.xyz All Rights Reserved.
 *
 * 感谢您选择Noark框架，希望我们的努力能为您提供一个简单、易用、稳定的服务器端框架 ！
 * 除非符合Noark许可协议，否则不得使用该文件，您可以下载许可协议文件：
 *
 *        http://www.noark.xyz/LICENSE
 *
 * 1.未经许可，任何公司及个人不得以任何方式或理由对本框架进行修改、使用和传播;
 * 2.禁止在本项目或任何子项目的基础上发展任何派生版本、修改版本或第三方版本;
 * 3.无论你对源代码做出任何修改和改进，版权都归Noark研发团队所有，我们保留所有权利;
 * 4.凡侵犯Noark版权等知识产权的，必依法追究其法律责任，特此郑重法律声明！
 */
package xyz.noark.codec.output;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import xyz.noark.codec.CodecConfig;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

class AbstractCodedOutputStreamTest {
/*
    @InjectMocks
    private AbstractCodedOutputStream codedOutputStream;

    @BeforeEach
    void setUp() {
        // Mock the Codec.config to provide a fixed initial buffer size
        CodecConfig mockConfig = mock(CodecConfig.class);
        when(mockConfig.getInitBufferSize()).thenReturn(16);
        // Codec.config = mockConfig;
        codedOutputStream = new AbstractCodedOutputStream() {
        };
    }

    @Test
    void writeLong_ZeroAndPositiveSmallValues() {
        long[] values = {
                0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 127
        };

        for (long value : values) {
            try(AbstractCodedOutputStream codedOutputStream = new CodedOutputStreamImpl()){
                codedOutputStream.writeLong(value);
                assertEquals((byte) value, codedOutputStream.byteArray[codedOutputStream.writeIndex - 1]);
            }
        }
    }

    @Test
    void writeLong_NegativeSmallValues() {
        long[] values = {
                -16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1
        };

        for (long value : values) {
            codedOutputStream.writeLong(value);
            // Check the two's complement for negative numbers
            assertEquals((byte) value, codedOutputStream.byteArray[codedOutputStream.writeIndex - 1]);
        }
    }

    @Test
    void writeLong_ByteValues() {
        long[] values = {
                Byte.MIN_VALUE, -129, -128, 127, 128, Byte.MAX_VALUE
        };

        for (long value : values) {
            codedOutputStream.writeLong(value);
            assertEquals(0x80 | (byte) (value >>> 8), codedOutputStream.byteArray[codedOutputStream.writeIndex - 2]);
            assertEquals((byte) value, codedOutputStream.byteArray[codedOutputStream.writeIndex - 1]);
        }
    }

    @Test
    void writeLong_ShortValues() {
        long[] values = {
                Short.MIN_VALUE, -32769, -32768, 32767, 32768, Short.MAX_VALUE
        };

        for (long value : values) {
            codedOutputStream.writeLong(value);
            //assertEquals(0x90, codedOutputStream.byteArray[codedOutputStream.writeIndex - 3]);
            //assertEquals((short) value, getShortFromByteArray(codedOutputStream.byteArray, codedOutputStream.writeIndex - 2));
        }
    }

    @Test
    void writeLong_IntegerValues() {
        long[] values = {
                Integer.MIN_VALUE, -2147483649L, -2147483648L, 2147483647L, 2147483648L, Integer.MAX_VALUE
        };

        for (long value : values) {
            codedOutputStream.writeLong(value);
            assertEquals(0x91, codedOutputStream.byteArray[codedOutputStream.writeIndex - 5]);
            assertEquals((int) value, getIntFromByteArray(codedOutputStream.byteArray, codedOutputStream.writeIndex - 4));
        }
    }

    @Test
    void writeLong_LongValues() {
        long[] values = {
                Long.MIN_VALUE, -922337203685477580L, -9223372036854775808L, 9223372036854775807L, 922337203685477580L, Long.MAX_VALUE
        };

        for (long value : values) {
            codedOutputStream.writeLong(value);
            assertEquals(0x95, codedOutputStream.byteArray[codedOutputStream.writeIndex - 9]);
            assertEquals(value, getLongFromByteArray(codedOutputStream.byteArray, codedOutputStream.writeIndex - 8));
        }
    }

    private short getShortFromByteArray(byte[] array, int index) {
        return (short) ((array[index] & 0xFF) | ((array[index + 1] & 0xFF) << 8));
    }

    private int getIntFromByteArray(byte[] array, int index) {
        return (array[index] & 0xFF) | ((array[index + 1] & 0xFF) << 8) |
                ((array[index + 2] & 0xFF) << 16) | ((array[index + 3] & 0xFF) << 24);
    }

    private long getLongFromByteArray(byte[] array, int index) {
        return (array[index] & 0xFFL) | ((array[index + 1] & 0xFFL) << 8) |
                ((array[index + 2] & 0xFFL) << 16) | ((array[index + 3] & 0xFFL) << 24) |
                ((array[index + 4] & 0xFFL) << 32) | ((array[index + 5] & 0xFFL) << 40) |
                ((array[index + 6] & 0xFFL) << 48) | ((array[index + 7] & 0xFFL) << 56);
    }*/
}
